﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OCR.Function
{
    public  class ModbusModule
    {
        public static  byte[] bytes_StartRealTime1 = new byte[] { 0x01, 0x06, 0x00, 0x00, 0x00, 0x01 };
        public static byte[] bytes_StopRealTime1 = new byte[] { 0x01, 0x06, 0x00, 0x00, 0x00, 0x02 };

        public static byte[] bytes_StartRealTime = new byte[] { 0x01, 0x06, 0x00, 0x00, 0x00, 0x01, 0x48, 0x0A };
        public static byte[] bytes_StopRealTime = new byte[] { 0x01, 0x06, 0x00, 0x00, 0x00, 0x02, 0x08, 0x0B };
        public static byte[] bytes_SingleTrigger = new byte[] { 0x01, 0x06, 0x00, 0x00, 0x00, 0x03, 0xC9, 0xCB };
        public static byte[] bytes_NG = new byte[] { 0x01, 0x06, 0x00, 0x01, 0x01, 0x01, 0x18, 0x5A };

        public static byte[] bytes_StartState = new byte[] { 0x01, 0x10, 0x00, 0x02, 0x00, 0x03, 0x06, 0x00, 0x01, 0x00, 0x01, 0x00, 0x64 };
        public static byte[] bytes_StopState = new byte[] { 0x01, 0x10, 0x00, 0x02, 0x00, 0x03, 0x06, 0x00, 0x02, 0x00, 0x01, 0x00, 0x64 };

        public static byte[] bytes_StartState_NoWidth = new byte[] { 0x01, 0x10, 0x00, 0x02, 0x00, 0x03, 0x06, 0x00, 0x01, 0x00, 0x01};
        public static byte[] bytes_StopState_NoWidth = new byte[] { 0x01, 0x10, 0x00, 0x02, 0x00, 0x03, 0x06, 0x00, 0x02, 0x00, 0x01};

        //public static string pulseWidth;

        SerialPort serialPort = new SerialPort();
        public ModbusModule()
        {

            serialPort.PortName = "COM1";//串口名称
            serialPort.BaudRate = 9600;//波特率
            serialPort.Parity = Parity.None;//奇偶校验
            serialPort.DataBits = 8;//数据位数
            serialPort.StopBits = StopBits.One;//停止位
            serialPort.Handshake = Handshake.None;//握手协议
            //serialPort.DataReceived += SerialPort_DataReceived;//接收到数据时的事件
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            byte[] array = new byte[sp.BytesToRead];
            int total = 0;
            while (total < array.Length)
            {
                int length = sp.Read(array, total, array.Length);
                total += length;
            }
            if (array.Length == total)
            {
                foreach (byte b in array)
                {
                    Console.WriteLine("十六进制：" + Convert.ToString(b, 16).ToUpper().PadLeft(2, '0'));

                }
                var str = string.Join("", array.Select(x => x.ToString("x2")));
                Console.WriteLine($"响应报文：{str}");
            }
        }

        public bool Open()
        {
            try
            {
                serialPort.Open();
                Console.WriteLine("打开串口");
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine($"打开串口失败：{e.Message}");
                return false;
            }
        }
        public bool Close()
        {
            try
            {
                serialPort.Close();
                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine($"关闭串口失败：{e.Message}");
                return false;
            }
        }

        public void SendData(byte[] data)
        {
            if (serialPort.IsOpen)
            {
                Console.WriteLine($"发送报文：{string.Join("", data.Select(x => x.ToString("x2")))}");
                serialPort.Write(data, 0, data.Length);
            }
        }

        public static byte[] CRC(byte[] data)
        {
            try
            {
                byte[] returnVal = new byte[2];
                int reg_crc = 0xffff;
                for (int i = 0; i < data.Length; i++)
                {
                    reg_crc ^= data[i];
                    for (int j = 0; j < 8; j++)
                    {
                        if ((reg_crc & 0x01) == 0x01)
                        {
                            /*LSB(bit 0)*/
                            reg_crc = (reg_crc >> 1) ^ 0xA001;

                        }
                        else
                        {
                            reg_crc = (reg_crc >> 1);
                        }
                    }
                }
                returnVal[1] = (byte)((reg_crc & 0xff00) >> 8);//CRC高位
                returnVal[0] = (byte)(reg_crc & 0x00ff);//CRC低位
                return returnVal;
            }
            catch
            {
                return null;
            }
        }
        public static byte[] MergeArray(byte[] array1)
        {
            byte[] byteTest = CRC(array1);

            List<byte> r = new List<byte>();
            r.AddRange(array1);
            r.AddRange(byteTest);
            byte[] l = r.ToArray();//List合并数组
            Console.WriteLine("List合并");
            foreach (var n in l)
            {
                Console.WriteLine(Convert.ToString(n, 16).ToUpper().PadLeft(2, '0'));
            }

            return l;
        }

        public static byte[] SetWidthByteArray(string pulseWidth, byte[] bytes)
        {
            List<byte> tempList = new List<byte>(bytes);
            tempList.Add(Convert.ToByte(int.Parse(pulseWidth) / 256));
            tempList.Add(Convert.ToByte(int.Parse(pulseWidth) % 256));
            foreach (var item in tempList)
            {
                //Console.WriteLine(Convert.ToString(item, 16).ToUpper().PadLeft(2, '0'));
            }
            return tempList.ToArray();
        }
    }
}
